
/**
 * 
 */
package com.project.jdbc.utils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.apache.commons.lang3.StringUtils;


/**
* 处理类的工具类. 例如反射
*/

public class ClassUtils {
	
	/**
	 * 获取一个实体类的属性值
	 * @param p
	 * @param o
	 * @return
	 * @throws Exception
	 */
	public static Object getPropertieValue(String p,Object o) throws Exception{
		Object _obj=null;
		for(Class<?> clazz = o.getClass(); clazz != Object.class;  clazz = clazz.getSuperclass()) {
			try{
			 PropertyDescriptor pd = new PropertyDescriptor(p, clazz);
				Method getMethod = pd.getReadMethod();// 获得get方法
				if(getMethod!=null){
					_obj= getMethod.invoke(o);
					break;
				}
			}catch(Exception e){
				return null;
			}
			
		}
		
		return _obj;
		
	}
	/**
	 * 设置实体类的属性值
	 * @param p
	 * @param o
	 * @return
	 * @throws Exception
	 */
	public static Object setPropertieValue(String p,Object o,Object value) throws Exception{
		Object _obj=null;
		for(Class<?> clazz = o.getClass(); clazz != Object.class;  clazz = clazz.getSuperclass()) {
			 PropertyDescriptor pd = new PropertyDescriptor(p, clazz);
				Method setMethod = pd.getWriteMethod();// 获得set方法
				if(setMethod!=null){
					setMethod.invoke(o, value);  
					break;
				}
			
		}
		
		return _obj;
		
	}
	
	/**
	 * 获取字段的返回类型
	 * @param p
	 * @param o
	 * @return
	 * @throws Exception
	 */
	public static Class getReturnType(String p,Class _clazz) throws Exception{
		
		Class  returnType=null;
		for(Class<?> clazz = _clazz; clazz != Object.class;  clazz = clazz.getSuperclass()) {
			 PropertyDescriptor pd = new PropertyDescriptor(p, clazz);
				Method getMethod = pd.getReadMethod();// 获得get方法
				if(getMethod!=null){
					returnType= getMethod.getReturnType();
					break;
				}
			
		}
		
		return returnType;
	}
	
	/**
	 * 是否是java的基本类型
	 * @param clazz
	 * @return
	 */
	public static  boolean isBaseType(Class clazz){
		if(clazz==null){
			return false;
		}
		String className=clazz.getName().toLowerCase();
		if(className.startsWith("java.")){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 得到实体的所有属性
	 * @param fileORvalue true表是返回属性，false表示返回多个问号
	 * */
	public static String getEntitySqlFile(Object obj,boolean fileORvalue)throws Exception{
		StringBuffer sbf = new StringBuffer();
		Method[] methods = obj.getClass().getDeclaredMethods();
		if(methods==null||methods.length<1)
			return null;
		int count = methods.length;
		//是否为自增列
		boolean identity = isIdentity(obj);
		for(int i=0;i<count;i++){
			boolean hasAnnotation = methods[i].isAnnotationPresent(Column.class);
			if(!hasAnnotation)
				continue;
			Column col = methods[i].getAnnotation(Column.class);
			String fileName = col.name();
			Object value = methods[i].invoke(obj);
			//如果id是空值且是自增列则执行下一个循环
			boolean hasidAnnotation = methods[i].isAnnotationPresent(Id.class);
			if(hasidAnnotation&&value==null&&identity)
				continue;
			//设置值或者
			if(fileORvalue)
				sbf.append(fileName);
			else
				sbf.append(":" + fileName);
				sbf.append(",");
		}
		return sbf.substring(0, sbf.lastIndexOf(",")).toString();
	}
	/**
	 * 得到主键的名称
	 * */
	public static String getEntityPKName(Object obj){
		Method[] methods = obj.getClass().getDeclaredMethods();
		int count = methods.length;
		for(int i=0;i<count;i++){
			boolean hasidAnnotation = methods[i].isAnnotationPresent(Id.class);
			if(!hasidAnnotation)
				continue;
			Column col = methods[i].getAnnotation(Column.class);
			return col.name();
		}
		return null;
	}
	/**
	 * 以键值形式返回属性的名与值
	 * */
	public static Map<String,Object> getEntityValue(Object obj)throws Exception{
		Method[] methods = obj.getClass().getDeclaredMethods();
		if(methods==null||methods.length<1)
			return null;
		int count = methods.length;
		//是否为自增列
		boolean identity = isIdentity(obj);
		Map<String,Object> map = new HashMap<String, Object>();
		for(int i=0;i<count;i++){
			boolean hasAnnotation = methods[i].isAnnotationPresent(Column.class);
			if(!hasAnnotation)
				continue;
			Column col = methods[i].getAnnotation(Column.class);
			String fileName = col.name();
			Object value = methods[i].invoke(obj);
			//如果id是空值且是自增列则执行下一个循环
			boolean hasidAnnotation = methods[i].isAnnotationPresent(Id.class);
			if(hasidAnnotation&&value==null&&identity)
				continue;
			map.put(fileName, value);
		}
		return map;
	}
	/**
	 * 生成字符串不会重复
	 * */
	public static String autoUUID(){
		String uuid = UUID.randomUUID().toString();
		//return uuid.replaceAll("-", "");
		return uuid;
	}
	public static boolean idisNull(Object obj) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		Method[] methods = obj.getClass().getDeclaredMethods();
		if(methods==null||methods.length<1)
			return false;
		for(Method method : methods){
			boolean hasAnnotation = method.isAnnotationPresent(Column.class);
			if(!hasAnnotation)
				continue;
			Column col = method.getAnnotation(Column.class);
			if(!"id".equals(col.name()))
				continue;
			if(method.invoke(obj)==null)
				return true;
		}
		return false;
	}
	/**
	 * 得到实体bean对应的表
	 * */
	public static String getTableName(Object obj) {
		Class cls = obj.getClass();
		if(cls.isAnnotationPresent(Table.class)){
			Table tab = (Table) cls.getAnnotation(Table.class);
			return tab.name();
		}
		return null;
	}
	/**
	 * 判断是否为自增列
	 * */
	public static boolean isIdentity(Object obj){
		Method[] methods = obj.getClass().getDeclaredMethods();
		if(methods==null||methods.length<1)
			return false;
		for(Method method : methods){
			boolean hasAnnotation = method.isAnnotationPresent(GeneratedValue.class);
			if(!hasAnnotation)
				continue;
			return true;
		}
		return false;
	}
	/**
	 * 得到一个实体类的插入语句
	 * */
	public static String insertSql(Object obj)throws Exception{
		String table = getTableName(obj);
		if(StringUtils.isEmpty(table))
			return null;
		StringBuffer sql = new StringBuffer("INSERT INTO ").append(table).append("(")
				.append(getEntitySqlFile(obj, true));
		
		StringBuffer valueSql = new StringBuffer(" values(").append(getEntitySqlFile(obj, false));
		sql.append(") ");
		valueSql.append(")");
		sql.append(valueSql.toString());
		return sql.toString();
	}
	/**
	 * 得到一个实体类的修改语句
	 * */
	public static String updateSql(Object obj) throws Exception{
		String table = getTableName(obj);
		if(StringUtils.isEmpty(table))
			return null;
		
		
		
		
		
		
		
		StringBuffer sbf = new StringBuffer();
		Method[] methods = obj.getClass().getDeclaredMethods();
		if(methods==null||methods.length<1)
			return null;
		int count = methods.length;
		String idInfo = null;
		for(int i=0;i<count;i++){
			boolean hasAnnotation = methods[i].isAnnotationPresent(Column.class);
			if(!hasAnnotation)
				continue;
			Column col = methods[i].getAnnotation(Column.class);
			String fileName = col.name();
			//如果id是空值且是自增列则执行下一个循环
			boolean hasidAnnotation = methods[i].isAnnotationPresent(Id.class);
			if(hasidAnnotation){
				idInfo = fileName + "=:" + fileName;
				continue;
			}
			sbf.append(fileName + "=:" + fileName);
			sbf.append(",");
		}
		StringBuffer sql = new StringBuffer("update ").append(table).append(" set ")
				.append(sbf.substring(0, sbf.lastIndexOf(",")).toString() + " where " + idInfo);
		return sql.toString();
	}
}
